
TOOL.Category		= "PC Mod - Wiring"
TOOL.Name			= "#Speaker Linker"
TOOL.Tab			= "PC Mod"
TOOL.Command		= nil
TOOL.ConfigName		= ""

cleanup.Register( "computers" )

if (CLIENT) then

	language.Add( 'Tool_speakerlinker_name', 'Speaker Linker' )
	language.Add( 'Tool_speakerlinker_desc', 'Connects speakers to a PC or splitter' )
	language.Add( 'Tool_speakerlinker_0', 'Left-Click: Select a speaker or splitter to connect. Right-Click: Unconnect a speaker or splitter.' )
	language.Add( 'Tool_speakerlinker_1', 'Left-Click: Select a PC or splitter to connect to. ' )

end

function TOOL:LeftClick( trace )

	// If the target is a player, stop here.
	if ( trace.Entity && trace.Entity:IsPlayer() ) then return false end
	
	// If there is no physics object, stop here.
	if ( SERVER && !util.IsValidPhysicsObject( trace.Entity, trace.PhysicsBone ) ) then return false end
	
	// Clients can stop here
	local iNum = self:NumObjects()
	if ( CLIENT ) then
		if ( iNum > 0 ) then self:ClearObjects() end
		return true
	end
	
	// Get the player
	local ply = self:GetOwner()
	
	// Get our object
	local Phys = trace.Entity:GetPhysicsObjectNum( trace.PhysicsBone )
	local id = trace.Entity:EntIndex()
	if (iNum == 0) then
		if (!trace.Entity.IsSpeaker) then
			ply:PrintMessage( HUD_PRINTTALK, "That entity is not a speaker!" )
			return false
		end
		if (trace.Entity.Data[ id ].PC) then
			ply:PrintMessage( HUD_PRINTTALK, "That entity is already linked to a PC!" )
			return false
		end
	end
	if (iNum == 1) then
		if (trace.Entity.IsSplitter) then
			if (self:GetEnt(1).IsSplitter) then
				ply:PrintMessage( HUD_PRINTTALK, "You can't link a splitter to a splitter!" )
				return false
			end
		else
			if (!trace.Entity.IsPC) then
				ply:PrintMessage( HUD_PRINTTALK, "That entity is not a PC!" )
				return false
			end
			if (trace.Entity.Data[ id ].Speaker) then
				ply:PrintMessage( HUD_PRINTTALK, "That entity is already linked to a speaker!" )
				return false
			end
		end
	end
	self:SetObject( iNum + 1, trace.Entity, trace.HitPos, Phys, trace.PhysicsBone, trace.HitNormal )

	if ( iNum > 0 ) then

		// Setup our variables
		local forcelimit = 0
		local addlength	 = 100
		local material 	 = "cable/cable2"
		local width 	 = 2
		local rigid	 	= false
		
		// Get information we're about to use
		local Ent1,  Ent2  = self:GetEnt(1),	 self:GetEnt(2)
		local Bone1, Bone2 = self:GetBone(1),	 self:GetBone(2)
		local WPos1, WPos2 = self:GetPos(1),	 self:GetPos(2)
		local LPos1, LPos2 = self:GetLocalPos(1),self:GetLocalPos(2)
		local length = ( WPos1 - WPos2):Length()

		// Create the rope
		local const, rope = constraint.Rope( Ent1, Ent2, Bone1, Bone2, LPos1, LPos2, length+addlength, 0, forcelimit, width, material, rigid )
		
		// Tell the PC that the speaker is linked & vice versa
		Ent1.Data[Ent1:EntIndex()].PC = Ent2
		if (Ent2.IsSplitter) then
			table.insert( Ent2.Data[Ent2:EntIndex()].Speakers, Ent1 )
		else
			Ent2.Data[Ent2:EntIndex()].Speaker = Ent1
		end
		Ent1.const = const
		Ent1.rope = rope
		
		
		// Clear the objects so we're ready to go again
		self:ClearObjects()
	else
		// Advance our stage
		self:SetStage( iNum+1 )
	end
	
	// This was successful!
	return true
end

function TOOL:RightClick( trace )
	
	// If the target is a player, stop here.
	if ( trace.Entity && trace.Entity:IsPlayer() ) then return false end
	
	// Clients stop here.
	if ( CLIENT ) then return true end
	
	// If there is no physics object, stop here.
	if ( SERVER && !util.IsValidPhysicsObject( trace.Entity, trace.PhysicsBone ) ) then return false end
	
	// Get the player
	local ply = self:GetOwner()
	
	// Get our object
	local Phys = trace.Entity:GetPhysicsObjectNum( trace.PhysicsBone )
	local id = trace.Entity:EntIndex()
	
	// Check the object
	if ((!trace.Entity.IsSpeaker) && (!trace.Entity.IsSplitter)) then
		ply:PrintMessage( HUD_PRINTTALK, "That entity is not a speaker!" )
		return false
	end
	if (!trace.Entity.Data[id].PC) then
		ply:PrintMessage( HUD_PRINTTALK, "That speaker is not linked!" )
		return false
	end
	
	// Unlink the entities
	local pc = trace.Entity.Data[id].PC
	trace.Entity.Data[id].PC = nil
	if (pc) then
		if (pc.IsSplitter) then
			for k, v in pairs( pc.Data[ pc:EntIndex() ].Speakers ) do
				if (v == trace.Entity) then
					table.remove( pc.Data[ pc:EntIndex() ].Speakers, k )
					break
				end
			end
		else
			pc.Data[ pc:EntIndex() ].Speaker = nil
		end
	end
	if (trace.Entity.rope) then trace.Entity.rope:Remove() end
	if (trace.Entity.const) then trace.Entity.const:Remove() end
	
	// This was successful!
	return true
end

function TOOL.BuildCPanel( CPanel )

	pc_maketoolinfo( CPanel:AddControl( "Label", { Text = "", Description = "" } ), "Speaker Linker", "Allows you to link a speaker to a PC." )

	// HEADER
	CPanel:AddControl( "Header", { Text = "#Tool_speaker_name", Description	= "#Tool_speaker_desc" }  )

end